package com.motong.gongdan.controller.system;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.motong.gongdan.config.CustomCellWriteHandler;
import com.motong.gongdan.config.ResponseData;
import com.motong.gongdan.config.auth.UserLoginToken;
import com.motong.gongdan.config.mqtt.MqttProviderConfig;
import com.motong.gongdan.constant.CommonConstant;
import com.motong.gongdan.entity.*;
import com.motong.gongdan.enums.ObjectType;
import com.motong.gongdan.mapper.DeviceStatusMapper;
import com.motong.gongdan.service.*;
import com.motong.gongdan.util.LoginUtil;
import com.motong.gongdan.vo.ExcelModel.CountListExcelModel;
import com.motong.gongdan.vo.ExcelModel.CountReportExcelModel;
import com.motong.gongdan.vo.H5Vo.device.query.CountDashboardQuery;
import com.motong.gongdan.vo.H5Vo.device.vo.CountDashboardVo;
import com.motong.gongdan.vo.system.common.query.IdValueQuery;
import com.motong.gongdan.vo.system.common.vo.CheckBox;
import com.motong.gongdan.vo.system.device.query.DeviceListQuery;
import com.motong.gongdan.vo.system.device.query.StartupRateDashboardQuery;
import com.motong.gongdan.vo.system.device.query.StatusDashboardQuery;
import com.motong.gongdan.vo.system.device.query.StatusLogQuery;
import com.motong.gongdan.vo.system.device.vo.CountReportVo;
import com.motong.gongdan.vo.system.device.vo.DeviceListVo;
import com.motong.gongdan.vo.system.device.vo.StartupRateDashboardVo;
import com.motong.gongdan.vo.system.device.vo.StatusDashboardVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "设备信息")
@RestController
@RequestMapping("/sys/device")
@Slf4j
public class DeviceController {

    @Resource
    private DeviceInfoService deviceInfoService;

    @Resource
    private DeviceUseLogService deviceUseLogService;

    @Resource
    private HandleLogService handleLogService;

    @Resource
    private UserService userService;

    @Resource
    private DeviceStatusService deviceStatusService;

    @Resource
    private MqttProviderConfig mqttProviderConfig;

    @Resource
    private DeviceStatusMapper deviceStatusMapper;

    @Resource
    private RedisTemplate<String, Objects> redisTemplate;

    @Resource
    private DeviceProduceLogService deviceProduceLogService;

    @Resource
    private LampRequestService lampRequestService;

//    @Resource
//    private H5DeviceController h5DeviceController;

//    @Resource
//    private RedisTemplate redisTemplate;

    @ApiOperation("获取设备列表")
    @PostMapping("/getList")
    @UserLoginToken
    public ResponseData<List<DeviceListVo>> getList(@RequestBody(required = false) DeviceListQuery query) {
        query = Optional.ofNullable(query).orElse(new DeviceListQuery());
        Page<DeviceListVo> data = deviceInfoService.getList(new Page<>(query.getPage(), query.getLimit()), query);
        return ResponseData.success(data.getRecords(), data.getTotal());
    }


    @ApiOperation("获取设备下拉label:设备名称 value: 设备id")
    @PostMapping("/dropDown")
    @UserLoginToken
    public ResponseData<List<CheckBox>> dropDown(@RequestBody(required = false) DeviceListQuery query) {
        query = Optional.ofNullable(query).orElse(new DeviceListQuery());
        LambdaQueryWrapper<DeviceInfo> qw = new LambdaQueryWrapper<DeviceInfo>().eq(Objects.nonNull(query.getGroupId()), DeviceInfo::getGroupId, query.getGroupId())
                .eq(Objects.nonNull(query.getDeviceNameOrSn()), DeviceInfo::getDeviceName, query.getDeviceNameOrSn());
        List<CheckBox> data = deviceInfoService.list(qw).stream().map(i -> new CheckBox().setLabel(i.getDeviceName()).setValue(i.getId().toString())).collect(Collectors.toList());
        return ResponseData.success(data);
    }


    @ApiOperation("编辑设备信息")
    @PostMapping("/edit")
    @UserLoginToken
    @Transactional(rollbackFor = Exception.class)
    public ResponseData<String> edit(@RequestBody DeviceInfo deviceInfo) {
        boolean isUpdate = Objects.nonNull(deviceInfo.getId());
        DeviceInfo oriDeviceInfo = new DeviceInfo();
        Integer currentUserId = LoginUtil.getLoginUserId();
        User currentUser = userService.getById(currentUserId);
        HandleLog handleLog = new HandleLog().setHandleCode(deviceInfo.getDeviceSn()).setHandleTime(new Date()).setType(ObjectType.device.getCode()).setHandleId(currentUserId);
//        if (Objects.nonNull(deviceInfo.getDeviceSn())) {
//            LambdaQueryWrapper<DeviceInfo> repeatQW = new LambdaQueryWrapper<DeviceInfo>().eq(DeviceInfo::getDeviceSn, deviceInfo.getDeviceSn()).ne(isUpdate, DeviceInfo::getId, deviceInfo.getId());
//            if (deviceInfoService.count(repeatQW) > 0) {
//                return ResponseData.fail("设备编号重复!");
//            }
//        }
        if (StringUtils.hasLength(deviceInfo.getRealDeviceSn())) {
            LoginUtil.setIgnoreFactory(true);
            LambdaQueryWrapper<DeviceInfo> realRealSnQW = new LambdaQueryWrapper<DeviceInfo>().eq(DeviceInfo::getRealDeviceSn, deviceInfo.getRealDeviceSn()).ne(isUpdate, DeviceInfo::getId, deviceInfo.getId());
            if (deviceInfoService.count(realRealSnQW) > 0) {
                return ResponseData.fail("设备序列号已在系统中存在!");
            }
            LoginUtil.setIgnoreFactory(false);
        }
        if (!isUpdate) {
            if (Objects.isNull(deviceInfo.getStatus())) {
                deviceInfo.setStatus(4);
            }
            handleLog.setHandleType("添加设备");
            deviceInfo.setCreateUser(currentUserId);
            deviceInfo.setCreateTime(new Date());
            handleLog.setHandleDetail(String.format("%s 创建了设备。", currentUser.getName()));
            handleLogService.save(handleLog);
        } else {
            handleLog.setHandleType("编辑设备");
            String deviceBindUser = Objects.nonNull(deviceInfo.getDeviceAdmin()) ? userService.getById(deviceInfo.getDeviceAdmin()).getName() : "无";
            String oriDeviceBindUser = Objects.nonNull(oriDeviceInfo.getDeviceAdmin()) ? userService.getById(oriDeviceInfo.getDeviceAdmin()).getName() : "无";
            if (!deviceBindUser.equals(oriDeviceBindUser)) {
                handleLog.setHandleDetail(String.format("%s 设置设备管理员由 %s 变为 %s", currentUser.getName(), oriDeviceBindUser, deviceBindUser));
                handleLogService.save(handleLog);
                handleLog.setId(null);
            }
            String deviceSn = Optional.ofNullable(deviceInfo.getDeviceSn()).orElse("");
            String oriDeviceSn = Optional.ofNullable(oriDeviceInfo.getDeviceSn()).orElse("");
            if (!deviceSn.equals(oriDeviceSn)) {
                handleLog.setHandleDetail(String.format("%s 设置设备编号由 %s 变为 %s", currentUser.getName(), oriDeviceSn, deviceSn));
                handleLogService.save(handleLog);
                handleLog.setId(null);
            }
            oriDeviceInfo = deviceInfoService.getById(deviceInfo.getId());
        }
        deviceInfo.setUpdateUser(currentUserId);
        deviceInfoService.saveOrUpdate(deviceInfo);
        if (StringUtils.hasLength(deviceInfo.getRealDeviceSn())) {
            try {
                if (Objects.nonNull(oriDeviceInfo.getRealDeviceSn())) {
                    mqttProviderConfig.unSubscribe(CommonConstant.MQTT_PREFIX.concat(oriDeviceInfo.getRealDeviceSn()));
                }
                mqttProviderConfig.subscribe(CommonConstant.MQTT_PREFIX.concat(deviceInfo.getRealDeviceSn()), 2);
            } catch (Exception e) {
                e.printStackTrace();
                log.error("订阅失败订阅主题为{}", CommonConstant.MQTT_PREFIX.concat(deviceInfo.getRealDeviceSn()));
            }
        }
        if ((Objects.isNull(deviceInfo.getBindUser()) && Objects.nonNull(Objects.requireNonNull(oriDeviceInfo).getBindUser())) || (
                Objects.nonNull(deviceInfo.getBindUser()) && Objects.nonNull(oriDeviceInfo.getBindUser()) && !deviceInfo.getBindUser().equals(oriDeviceInfo.getBindUser()))) {
            // 更新使用记录
            if (Objects.nonNull(deviceInfo.getBindUser())) {
                DeviceUseLog deviceUseLog = new DeviceUseLog().setDeviceId(deviceInfo.getId()).setUserId(currentUserId).setStartTime(new Date());
                deviceUseLogService.save(deviceUseLog);
            }
            if (Objects.nonNull(oriDeviceInfo.getBindUser())) {
                LambdaQueryWrapper<DeviceUseLog> lastEnd = new LambdaQueryWrapper<DeviceUseLog>().eq(DeviceUseLog::getDeviceId, deviceInfo.getId())
                        .eq(DeviceUseLog::getUserId, oriDeviceInfo.getBindUser()).orderByDesc(DeviceUseLog::getDeviceId).isNull(DeviceUseLog::getEndTime);
                DeviceUseLog lastLog = deviceUseLogService.getOne(lastEnd).setEndTime(new Date());
                deviceUseLogService.updateById(lastLog);
            }
        }
        return ResponseData.success(isUpdate ? "编辑成功!" : "添加成功!");
    }


    @ApiOperation("删除设备信息")
    @PostMapping("/del")
    @UserLoginToken
    @Transactional
    public ResponseData<String> del(@RequestBody IdValueQuery query) {
        if (StringUtils.hasLength(query.getIds())) {
            List<String> removeIds = Arrays.asList(query.getIds().split(","));
            List<DeviceInfo> removeDevice = deviceInfoService.listByIds(removeIds);
            removeDevice.forEach(i -> {
                if (StringUtils.hasLength(i.getRealDeviceSn())) {
                    mqttProviderConfig.unSubscribe(CommonConstant.MQTT_PREFIX.concat(i.getRealDeviceSn()));
                }
            });
            lampRequestService.remove(new LambdaQueryWrapper<LampRequest>().in(LampRequest::getDeviceId, removeIds));
            deviceUseLogService.remove(new LambdaQueryWrapper<DeviceUseLog>().in(DeviceUseLog::getDeviceId, removeIds));
            deviceInfoService.removeByIds(removeIds);
            deviceStatusMapper.delete(new LambdaQueryWrapper<DeviceStatus>().in(DeviceStatus::getDeviceId, removeIds));
            deviceUseLogService.remove(new LambdaQueryWrapper<DeviceUseLog>().in(DeviceUseLog::getDeviceId, removeIds));
            deviceProduceLogService.remove(new LambdaQueryWrapper<DeviceProduceLog>().in(DeviceProduceLog::getDeviceId, removeIds));
        }
        return ResponseData.success("删除成功!");
    }


    @ApiOperation("批量解绑")
    @PostMapping("/releaseBatch")
    @UserLoginToken
    public ResponseData<String> releaseBatch(@RequestBody IdValueQuery query) {
        if (!StringUtils.hasLength(query.getIds())) {
            return ResponseData.fail("必要参数不能为空!");
        }
        List<String> ids = Arrays.asList(query.getIds().split(","));
        if (!CollectionUtils.isEmpty(ids)) {
            LambdaQueryWrapper<DeviceUseLog> logQW = new LambdaQueryWrapper<DeviceUseLog>().in(DeviceUseLog::getDeviceId, ids).isNull(DeviceUseLog::getEndTime);
            List<DeviceUseLog> log = deviceUseLogService.list(logQW).stream().map(i -> i.setEndTime(new Date())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(log)) {
                deviceUseLogService.updateBatchById(log);
            }
            LambdaUpdateWrapper<DeviceInfo> updateUW = new LambdaUpdateWrapper<DeviceInfo>().set(DeviceInfo::getBindUser, null).in(DeviceInfo::getId, ids);
            deviceInfoService.update(updateUW);
        }
        return ResponseData.success("解绑成功!");
    }


    @UserLoginToken
    @ApiOperation("设备导入")
    @PostMapping("/deviceImport")
    public ResponseData<String> deviceImport(MultipartFile file, Long groupId) throws IOException {
        ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
        List<Map> mapData = reader.read(1, 2, Map.class);
        if (!CollectionUtils.isEmpty(mapData)) {
            List<DeviceInfo> deviceInfos = new ArrayList<>();
            mapData.forEach(i -> {
                if (Objects.nonNull(i.get("设备名称")) && Objects.nonNull(i.get("设备编号"))) {
                    deviceInfos.add(new DeviceInfo().setDeviceNameByObject(i.get("设备名称")).setGroupId(groupId).setCreateTime(new Date()).setCreateUser(LoginUtil.getLoginUserId())
                            .setDeviceSnByObject(i.get("设备编号")).setRemarkByObject(i.get("备注")).setDeviceAdminNameByObject(i.get("设备管理员")));
                }
            });
            if (!CollectionUtils.isEmpty(deviceInfos)) {
                // 编号过滤后的数据
                List<DeviceInfo> afterFilterData = new ArrayList<>();
                // 设置管理员账号
                Map<String, Integer> userNameIdMap = new HashMap<>(deviceInfos.size());
                Set<String> userNames = deviceInfos.stream().map(DeviceInfo::getDeviceAdminName).collect(Collectors.toSet());
                userService.list(new LambdaQueryWrapper<User>().in(User::getName, userNames)).forEach(i -> userNameIdMap.put(i.getName(), i.getId()));
                // 编号已存在set
                Set<String> existSns = new HashSet<>(deviceInfos.size());
                Set<String> sns = deviceInfos.stream().map(DeviceInfo::getDeviceSn).collect(Collectors.toSet());
                deviceInfoService.list(new LambdaQueryWrapper<DeviceInfo>().in(DeviceInfo::getDeviceSn, sns)).forEach(i -> existSns.add(i.getDeviceSn()));
                deviceInfos.forEach(i -> {
                    if (existSns.add(i.getDeviceSn())) {
                        i.setDeviceAdmin(userNameIdMap.get(i.getDeviceAdminName())).setStatus(4);
                        afterFilterData.add(i);
                        if (StringUtils.hasLength(i.getRealDeviceSn())) {
                            try {
                                mqttProviderConfig.subscribe(CommonConstant.MQTT_PREFIX.concat(i.getRealDeviceSn()), 2);
                            } catch (Exception e) {
                                log.error("订阅失败订阅主题为{}", CommonConstant.MQTT_PREFIX.concat(i.getRealDeviceSn()));
                            }

                        }
                    }
                });
                if (!CollectionUtils.isEmpty(afterFilterData)) {
                    deviceInfoService.saveBatch(afterFilterData);
                }
            }
        }
        return ResponseData.success("导入成功!");
    }

    @UserLoginToken
    @ApiOperation("设备状态看板")
    @PostMapping("/statusDashboard")
    public ResponseData<StatusDashboardVo> statusDashboard(@RequestBody StatusDashboardQuery query) {
        StatusDashboardVo data = deviceStatusService.statusDashboard(query);
        return ResponseData.success(data);
    }


    @UserLoginToken
    @ApiOperation("设备状态记录")
    @PostMapping("/statusLog")
    public ResponseData<List<DeviceStatus>> statusLog(@RequestBody(required = false) StatusLogQuery query) {
        query = Optional.ofNullable(query).orElse(new StatusLogQuery());
//        StatusLogQuery finalQuery = query;
        Page<DeviceStatus> page =  deviceStatusService.statusLog(new Page<>(query.getPage(), query.getLimit()),query);
//        LambdaQueryWrapper<DeviceStatus> deviceStatusQW = new LambdaQueryWrapper<DeviceStatus>().eq(Objects.nonNull(query.getDeviceId()), DeviceStatus::getDeviceId, query.getDeviceId())
//                .ge(Objects.nonNull(finalQuery.getTimeStart()), DeviceStatus::getCreateTime, finalQuery.getTimeStart())
//                .and(i -> i.and(j -> j.le(Objects.nonNull(finalQuery.getTimeEnd()), DeviceStatus::getCreateTime, finalQuery.getTimeEnd()).or().isNull(DeviceStatus::getDuration)));
//        Page<DeviceStatus> page = deviceStatusService.page(new Page<>(query.getPage(), query.getLimit()), deviceStatusQW);
        page.getRecords().forEach(i -> {
            if (Objects.isNull(i.getDuration())) {
                Date date = new Date();
                i.setDuration(DateUtil.between(i.getCreateTime(), date, DateUnit.SECOND));
                i.setEndTime(date);
            } else {
                i.setEndTime(DateUtil.offsetSecond(i.getCreateTime(), Convert.toInt(i.getDuration())));
            }
            i.setCreateTimestamp(i.getCreateTime().getTime());
        });
        return ResponseData.success(page.getRecords(), page.getTotal());
    }

    @UserLoginToken
    @ApiOperation("开机率看板")
    @PostMapping("/startupRateDashboard")
    public ResponseData<List<StartupRateDashboardVo>> startupRateDashboard(@RequestBody(required = false) StartupRateDashboardQuery query) {
        query = Optional.ofNullable(query).orElse(new StartupRateDashboardQuery());
        // 获取绿灯比率前n个的设备
        Page<StartupRateDashboardVo> page = deviceStatusMapper.getTopGreenRateDevice(new Page<>(query.getPage(), query.getLimit()), query);
        return ResponseData.success(page.getRecords(), page.getTotal());
    }


    /*————————————————————————————————————————计数相关————————————————————————————————————————————*/


    @UserLoginToken
    @ApiOperation("计数看板设备条件缓存")
    @PostMapping("/cacheCountCondition")
    public ResponseData<String> cacheCountCondition(@RequestBody CountDashboardQuery query) {
        query = Optional.ofNullable(query).orElse(new CountDashboardQuery());
        query.setClient("H5");
        if (Objects.nonNull(query.getDeviceId()) && (Objects.nonNull(query.getStartTime()) || Objects.nonNull(query.getNumberPulses()))) {
            String cacheNamePrefix = "device:countDashboard:".concat(query.getClient()).concat(":");
            Object oriCacheCondition = redisTemplate.opsForHash().get(CommonConstant.SEARCH_CONDITION_HASH_KEY, cacheNamePrefix + query.getDeviceId());
            if (Objects.nonNull(oriCacheCondition)) {
                CountDashboardQuery cacheCondition = JSONUtil.toBean(oriCacheCondition.toString(), CountDashboardQuery.class);
                query.setStartTime(Optional.ofNullable(query.getStartTime()).orElse(cacheCondition.getStartTime()));
            }
            redisTemplate.opsForHash().put(CommonConstant.SEARCH_CONDITION_HASH_KEY, cacheNamePrefix + query.getDeviceId(), JSONUtil.toJsonStr(query));
        }
        return ResponseData.success("成功!");
    }


    @UserLoginToken
    @ApiOperation("计数看板")
    @PostMapping("/countDashboard")
    public ResponseData<List<CountDashboardVo>> countDashboard(@RequestBody(required = false) CountDashboardQuery query) {
        query = Optional.ofNullable(query).orElse(new CountDashboardQuery());
        query.setClient("H5");
        query = Optional.ofNullable(query).orElse(new CountDashboardQuery());
        String cacheNamePrefix = "device:countDashboard:".concat(query.getClient()).concat(":");
        Page<CountDashboardVo> data = deviceProduceLogService.countDashboard(new Page<>(query.getPage(), query.getLimit()), query, cacheNamePrefix);
        return ResponseData.success(data.getRecords(), data.getTotal());
    }

    @UserLoginToken
    @ApiOperation("计数报表")
    @PostMapping("/countReport")
    public ResponseData<List<CountReportVo>> countReport(@RequestBody(required = false) CountDashboardQuery query) {
        query = Optional.ofNullable(query).orElse(new CountDashboardQuery());
        Page<CountReportVo> data = deviceProduceLogService.countReport(new Page<>(query.getPage(), query.getLimit()), query);
        return ResponseData.success(data.getRecords(), data.getTotal());
    }


    @UserLoginToken
    @ApiOperation("小时计数报表")
    @PostMapping("/hourCountReport")
    public ResponseData<List<CountReportVo>> hourCountReport(@RequestBody(required = false) CountDashboardQuery query) {
        query = Optional.ofNullable(query).orElse(new CountDashboardQuery());
        Page<CountReportVo> data = deviceProduceLogService.countReport(new Page<>(query.getPage(), query.getLimit()), query);
        List<CountReportVo> timeCountDate = deviceProduceLogService.hourCountReport(query);
        Map<Long, List<CountReportVo>> deviceDataGroup = timeCountDate.stream().collect(Collectors.groupingBy(CountReportVo::getDeviceId));
        data.getRecords().forEach(i -> {
            HashMap<Integer, Long> timeCountMap = new HashMap<>(24);
            for (int d = 0; d < 24; d++) {
                timeCountMap.put(d, 0L);
            }
            deviceDataGroup.get(i.getDeviceId()).forEach(e -> timeCountMap.put(e.getTimeOfHour(), e.getTotalNum()));
            i.setTimeCountMap(timeCountMap);
        });
        return ResponseData.success(data.getRecords(), data.getTotal());
    }


    @UserLoginToken
    @ApiOperation("计数明细")
    @PostMapping("/countList")
    public ResponseData<List<DeviceProduceLog>> countList(@RequestBody(required = false) CountDashboardQuery query) {
        query = Optional.ofNullable(query).orElse(new CountDashboardQuery());
        Page<DeviceProduceLog> page = new Page<>(query.getPage(), query.getLimit());
        LambdaQueryWrapper<DeviceProduceLog> queryWrapper = new LambdaQueryWrapper<DeviceProduceLog>()
                .eq(Objects.nonNull(query.getDeviceId()), DeviceProduceLog::getDeviceId, query.getDeviceId())
                .ge(Objects.nonNull(query.getStartTime()), DeviceProduceLog::getCreateTime, query.getStartTime())
                .le(Objects.nonNull(query.getEndTime()), DeviceProduceLog::getCreateTime, query.getEndTime())
                .ge(Objects.nonNull(query.getStartSecond()), DeviceProduceLog::getTimeInterval, query.getStartSecond())
                .le(Objects.nonNull(query.getEndSecond()), DeviceProduceLog::getTimeInterval, query.getEndSecond());
        Page<DeviceProduceLog> data = deviceProduceLogService.page(page, queryWrapper);
        return ResponseData.success(data.getRecords(), data.getTotal());
    }

    /*----------------------导出------------------------*/

    @UserLoginToken
    @PostMapping("/exportCountReport")
    @ApiOperation(value = "导出计数报表")
    public void outCountReportExcel(@RequestBody(required = false) CountDashboardQuery query, HttpServletResponse response) {
        List<CountReportVo> data = this.countReport(query).getData();
        if (!CollectionUtils.isEmpty(data)) {
            try {
                List<CountReportExcelModel> exportData = data.stream().map(i -> {
                    CountReportExcelModel countReportExcelModel = new CountReportExcelModel();
                    BeanUtil.copyProperties(i, countReportExcelModel);
                    return countReportExcelModel;
                }).collect(Collectors.toList());
                String fileName = "计数报表" + System.currentTimeMillis() + ".xlsx";
                response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
                EasyExcel.write(response.getOutputStream()).registerWriteHandler(new CustomCellWriteHandler()).sheet("计数报表导出数据").head(CountReportExcelModel.class).doWrite(exportData);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    @UserLoginToken
    @PostMapping("/exportCountList")
    @ApiOperation(value = "导出计数明细")
    public void outCountListExcel(@RequestBody(required = false) CountDashboardQuery query, HttpServletResponse response) {
        List<DeviceProduceLog> data = this.countList(query).getData();
        if (!CollectionUtils.isEmpty(data)) {
            try {
                List<CountListExcelModel> exportData = data.stream().map(i -> {
                    CountListExcelModel countListExcelModel = new CountListExcelModel();
                    BeanUtil.copyProperties(i, countListExcelModel);
                    return countListExcelModel;
                }).collect(Collectors.toList());
                String fileName = "计数明细" + System.currentTimeMillis() + ".xlsx";
                response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
                EasyExcel.write(response.getOutputStream()).registerWriteHandler(new CustomCellWriteHandler()).sheet("计数明细导出数据").head(CountListExcelModel.class).doWrite(exportData);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
